#pragma once

#ifndef _DROPLET_RENDERER
#define _DROPLET_RENDERER

#include "OGLGlobals.h"
#include "OGLRenderer.h"
#include "OGLViewControl.h"
#include "OGLWindowControl.h"
#include "RenderableSimpleDroplet.h"

#include <gl/glew.h>
#include <gl/GLU.h>
#include <gl/glfw.h>

#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <vector>

#define VERTEX_SHADER_FILE "SimpleVertexShader.glsl"
#define FRAGMENT_SHADER_FILE "SimpleFragmentShader.glsl"
#define DROPLET_MODEL_FILE "SimpleDroplet.txt"
#define FLOOR_MODEL_FILE "SimpleFloor.txt"

// Droplet Simulator specific constants
#define NUM_ROBOTS 1024
#define NUM_TILE_ROWS 12
#define NUM_TILE_COLS 12	// Rows * Cols of tiles make up the floor
#define DROPLET_DIAMETER 4.0f	// in cm
#define TILE_LENGTH 25.0f // in cm (tiles are square)

class DropletRenderer : public OGLRenderer
{
private :

	std::vector<RenderableSimpleDroplet *> renderableObjects;
	GLuint vaoID, programID, vertexShaderID, fragmentShaderID;
	bool firstUpdate;
	
	// Simulator specific values
	float dropletAngle;

	// Use srand() fisrt to seed!
	float getRandomf(float min, float max);

	OGLResult createVAO(void);
	OGLResult loadShader(
		std::string shaderFilepath, 
		GLenum shaderType, 
		GLuint *shaderID
	);
	OGLResult loadProgram(
		std::string vertexShaderFilepath, 
		std::string fragmentShaderFilepath
	);
	RenderableSimpleDroplet *createRenderableObject(
		std::string modelFilepath,
		glm::vec3 startPosition,
		GLenum dataType,
		GLenum usageType,
		GLenum drawType);

	OGLResult destroyArrayObjects(void);
	OGLResult destroyShadersAndPrograms(void);

public :
	
	DropletRenderer(void);
	~DropletRenderer(void);

	void LoopInitialize(void);
	void LoopIterate(void);
	void LoopUpdate(void);
	void LoopComplete(void);

};

#endif